package qf.index;//package com.qf.index;
//
//import cn.hutool.core.collection.ConcurrentHashSet;
//import cn.hutool.core.io.FileUtil;
//import cn.hutool.core.io.IoUtil;
//import cn.hutool.core.util.NumberUtil;
//import cn.hutool.db.Db;
//import cn.hutool.db.Entity;
//
//import java.io.BufferedInputStream;
//import java.io.BufferedReader;
//import java.io.IOException;
//import java.sql.SQLException;
//import java.text.SimpleDateFormat;
//import java.time.LocalDateTime;
//import java.util.*;
//import java.util.concurrent.ConcurrentHashMap;
//
/// **
// * 全文扫尾程序，本程度分两部分，一是本地已经存在的PDF文件（含三个表、dir命令、以及已经给淘宝的），另一部分是最新的论文表（含两个版本的NC和UT表，以及服务器自动下载的日志，上次扫尾的文件等），结果本地已存在，则不再扫尾，不存在的，插入继续扫尾表。
// * 其二，本程序还将插入本地存在，而全文服务器上所不存在的全文，插入上传表。同时在计算的过程中，还对过程数据进行了插表，并产生了UT号也PMID号相等的映射表。
// * 需要注意的地方，一是两个NC表的电子优先部分，不作扫尾；二是UT表中若同时存在UT和PMID号，有任一个都不扫尾，若两个都不存在，优先扫尾PMID号。
// * 2021.12.05 贾新志 到2012.12.09日，与张哥已经全面核对，完全一致。 2022.03.31为需要继续扫尾的部分，添加上出版年。
// * <p>
// * 2023-10-11 22:35:47 现在开始： 9999001 -- 10000000 总条数： 41162 目前已处理： 10000 表名： dir.wospdf_20231010_fullpath
// * 2023-10-11 22:48:41 现在开始： 19999001 -- 20000000 总条数： 41162 目前已处理： 20000 表名： dir.wospdf_20231010_fullpath
// * 2023-10-11 23:01:11 现在开始： 29999001 -- 30000000 总条数： 41162 目前已处理： 30000 表名： dir.wospdf_20231010_fullpath
// * 2023-10-11 23:13:54 现在开始： 39999001 -- 40000000 总条数： 41162 目前已处理： 40000 表名： dir.wospdf_20231010_fullpath
// * 2023-10-11 23:27:27 现在开始： 9999001 -- 10000000 总条数： 34266 目前已处理： 10000 表名： dir.ncbijournalpdf_20231010_fullpath
// * 2023-10-11 23:39:46 现在开始： 19999001 -- 20000000 总条数： 34266 目前已处理： 20000 表名： dir.ncbijournalpdf_20231010_fullpath
// * 2023-10-11 23:52:08 现在开始： 29999001 -- 30000000 总条数： 34266 目前已处理： 30000 表名： dir.ncbijournalpdf_20231010_fullpath
// * 2023-10-12 00:10:08 ①_1 ncbiPdfTable->localDirSet.size(): 29644404  内存申请：90 Gb 空余：76 Gb 获取：90 Gb
// * 2023-10-12 00:17:28 ①_2 wosPdfTable->localDirSet.size(): 60754264  内存申请：90 Gb 空余：69 Gb 获取：90 Gb
// * 2023-10-12 00:17:35 ①_3 googlePdfTable->localDirSet.size(): 61326911  内存申请：90 Gb 空余：57 Gb 获取：90 Gb
// * 2023-10-12 00:18:11 ①_4 sciHubPdfTable->localDirSet.size(): 66295188  内存申请：90 Gb 空余：55 Gb 获取：90 Gb
// * 2023-10-12 00:19:09 ②_1 dirFilePathA->localDirSet.size(): 66307865  内存申请：88 Gb 空余：47 Gb 获取：88 Gb
// * 2023-10-12 00:19:09 ②_3 taoBaoFilePath->localDirSet.size(): 66556563  内存申请：88 Gb 空余：47 Gb 获取：88 Gb
// * 2023-10-12 00:19:10 ②_4 removeFilePath->localDirSet.size(): 67832419  内存申请：88 Gb 空余：44 Gb 获取：88 Gb
// * 2023-10-12 02:03:54 ③_1 ncbiHtmlTable->continueSaoWeiMap.size(): 101890  内存申请：89 Gb 空余：26 Gb 获取：89 Gb
// * 2023-10-12 02:17:19 ③_2 ncbiArticleTable->continueSaoWeiMap.size(): 109347  内存申请：90 Gb 空余：32 Gb 获取：90 Gb
// * 2023-10-12 02:46:34 ③_3 wosArticleTable->continueSaoWeiMap.size(): 913322  内存申请：89 Gb 空余：20 Gb 获取：89 Gb
// * 2023-10-12 02:47:40 ③_4 houTaiTable->continueSaoWeiMap.size(): 981868  内存申请：88 Gb 空余：28 Gb 获取：88 Gb
// * 2023-10-12 02:50:01 ③_5 logFilePath->continueSaoWeiMap.size(): 992195  内存申请：89 Gb 空余：13 Gb 获取：89 Gb
// * 2023-10-12 02:50:59 ④_1 saoWeiTable->utMappingPmidMap.size(): 25663109  内存申请：89 Gb 空余：26 Gb 获取：89 Gb
// * 2023-10-12 02:57:32 ④_2 utMappingPmidTable->utPmidSet.size(): 25663109  内存申请：85 Gb 空余：13 Gb 获取：85 Gb
// * 2023-10-12 02:57:32 程序全部结束，总用时：274 分钟。
// */
//
//public class PdfDownloadUpload {
//
//    public static void main(String[] args) throws SQLException, IOException {
//        SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
//        System.out.println("\033[31;1m" + format.format(new Date()) + " 程序开始了~~~ " + "\033[0m");
//        long t0 = System.currentTimeMillis();
//
//        String limit = "";
////        String limit = " limit 1";
//        Integer onePageNum = 1000;
//
//        // 是否把计算过程中的log日志插入表中，true是插入。
//        boolean isInsertLog = false;
//
//        // 获取当前年
//        String nowYear = Utils.getNowYear().toString();
//        String uploadTable = "dir.upload_pdf_server_table_0331";
//        String saoWeiTable = "dir.continue_sao_wei_table_0331";
//        String dirLogSaoWeiTable = "dir.dir_log_sao_wei_table";
//        String utMappingPmidTable = "dir.ut_mapping_pmid_table";
//        String localDirSetTable = "dir.local_dir_set";
//
//        Db.use().execute("truncate table " + uploadTable);
//        Db.use().execute("truncate table " + saoWeiTable);
//        Db.use().execute("truncate table " + utMappingPmidTable);
//        if (isInsertLog) {
//            Db.use().execute("truncate table " + dirLogSaoWeiTable);
//            Db.use().execute("truncate table " + localDirSetTable);
//            Db.use().execute("truncate table " + uploadTable);
//        }
//
//        // 本地的dir文件Set
//        Set<String> localDirSet = new ConcurrentHashSet<>();
//        Set<String> doiPmidSet = new ConcurrentHashSet<>();
//        Map<String, Set<String>> continueSaoWeiMap = new ConcurrentHashMap<>();
//        Map<String, Set<Integer>> utMappingPmidMap = new ConcurrentHashMap<>();
//        Map<String, Integer> utOrPmidAndYearMap = new ConcurrentHashMap<>();
//
//        Set<String> dirSet = new ConcurrentHashSet<>();
//        Set<String> logSet = new ConcurrentHashSet<>();
//        Set<String> saoWeiSet = new ConcurrentHashSet<>();
//
//        /**
//         * 1、本地的dir文件；2、服务器上的全文表；3、已给给淘宝的记录；
//         */
//        // 服务器上的全文表，仅一个fullpath字段，比如：2018/20180617/Serum-gastrin in vitiligo [PMIDS4132789].pdf
//        String wosPdfTable = "dir.wospdf_20241213_fullpath";
//        String ncbiPdfTable = "dir.ncbijournalpdf_20250116_fullpath";
//        String googlePdfTable = "dir.googlepdf_20241213_fullpath";
//        String sciHubPdfTable = "dir.scihubpdf_20241213_fullpath";
//
//        // 为三个表插入`file_id`，用于比对程序是否有误，本次核对结束后，下面的三行程序可以不用的。
////        readDataTable(wosPdfTable, onePageNum, limit, "pid", "fullpath", localDirSet, "update", continueSaoWeiMap, nowYear, doiPmidSet, utMappingPmidMap, utOrPmidAndYearMap, true);
////        readDataTable(ncbiPdfTable, onePageNum, limit, "pid", "fullpath", localDirSet, "update", continueSaoWeiMap, nowYear, doiPmidSet, utMappingPmidMap, utOrPmidAndYearMap, true);
////        readDataTable(googlePdfTable, onePageNum, limit, "pid", "fullpath", localDirSet, "update", continueSaoWeiMap, nowYear, doiPmidSet, utMappingPmidMap, utOrPmidAndYearMap, true);
////        readDataTable(sciHubPdfTable, onePageNum, limit, "pid", "fullpath", localDirSet, "update", continueSaoWeiMap, nowYear, doiPmidSet, utMappingPmidMap, utOrPmidAndYearMap, true);
//
//        readDataTable(ncbiPdfTable, onePageNum, limit, "pid", "fullpath", localDirSet, "dir", continueSaoWeiMap, nowYear, doiPmidSet, utMappingPmidMap, utOrPmidAndYearMap, false);
//        System.out.println("\033[31;1m" + format.format(new Date()) + " ①_1 ncbiPdfTable->localDirSet.size(): " + localDirSet.size() + " " + printMemoryStr() + "\033[0m");
//
////        readDataTable(wosPdfTable, onePageNum, limit, "pid", "fullpath", localDirSet, "dir", continueSaoWeiMap, nowYear, doiPmidSet, utMappingPmidMap, utOrPmidAndYearMap, false);
//        System.out.println("\033[31;1m" + format.format(new Date()) + " ①_2 wosPdfTable->localDirSet.size(): " + localDirSet.size() + " " + printMemoryStr() + "\033[0m");
//
////        readDataTable(googlePdfTable, onePageNum, limit, "pid", "fullpath", localDirSet, "dir", continueSaoWeiMap, nowYear, doiPmidSet, utMappingPmidMap, utOrPmidAndYearMap, false);
//        System.out.println("\033[31;1m" + format.format(new Date()) + " ①_3 googlePdfTable->localDirSet.size(): " + localDirSet.size() + " " + printMemoryStr() + "\033[0m");
//
////        readDataTable(sciHubPdfTable, onePageNum, limit, "pid", "fullpath", localDirSet, "dir", continueSaoWeiMap, nowYear, doiPmidSet, utMappingPmidMap, utOrPmidAndYearMap, false);
//        System.out.println("\033[31;1m" + format.format(new Date()) + " ①_4 sciHubPdfTable->localDirSet.size(): " + localDirSet.size() + " " + printMemoryStr() + "\033[0m");
//
//        // 本地的dir文件，文本内一行一个dir文件，比如：E:\E\SCI_HUB_44P\web0923\5\A[WOSN000612597000006].PDF   dirFilePathA必须是待上传的PDF的文件夹。
//        String dirFilePathA = "E:\\gDiskPdf\\dir_2025_01_16.txt";
//        uploadDirFile(dirFilePathA, localDirSet, uploadTable); // 本地有，而服务器上无的，添加到上传表中。
//
//        readDirFile(dirFilePathA, localDirSet, dirSet, dirLogSaoWeiTable, isInsertLog);
//        System.out.println("\033[31;1m" + format.format(new Date()) + " ②_1 dirFilePathA->localDirSet.size(): " + localDirSet.size() + " " + printMemoryStr() + "\033[0m");
//
//        String dirFilePathB = "E:\\dir_e_1213.txt";
////        readDirFile(dirFilePathB, localDirSet, dirSet, dirLogSaoWeiTable, isInsertLog);
//        System.out.println("\033[31;1m" + format.format(new Date()) + " ②_2 dirFilePathB->localDirSet.size(): " + localDirSet.size() + " " + printMemoryStr() + "\033[0m");
//
//        // 已给淘宝的记录，文本内一行一条记录，只有PMID号，比如： 34281884
//        String taoBaoFilePath = "C:\\扫尾文件\\已给淘宝第1到74批_780608.txt";
//        readTaoBaoFile(taoBaoFilePath, localDirSet);
//        System.out.println("\033[31;1m" + format.format(new Date()) + " ②_3 taoBaoFilePath->localDirSet.size(): " + localDirSet.size() + " " + printMemoryStr() + "\033[0m");
//
//        // 已经处理过很多遍，不打算再次处理的记录，包括UT、PM、GG三种，添加到localDirSet，相当于给予移删，不再处理了。文本内一行一条记录，比如： UT000766308400017
//        String removeFilePath = "C:\\扫尾文件\\continue_sao_wei_table_waive_2024_03_06.txt";
////        readRemoveFile(removeFilePath, localDirSet);
//        System.out.println("\033[31;1m" + format.format(new Date()) + " ②_4 removeFilePath->localDirSet.size(): " + localDirSet.size() + " " + printMemoryStr() + "\033[0m");
//
//        /**
//         * 1、最新的论文表；2、服务器上的下载日志；3、文献员后台的文件；4、上次留下的需要扫尾的文件；
//         */
//        // 最新的论文表
//        String ncbiHtmlTable = "html.pmid_html_down_all_2024_10_29_37995593"; // 36606974
////        readDataTable(ncbiHtmlTable, onePageNum, limit, "id", "pmid`,`citationDoi`,`citationTitle`,`text`,`redirection_notice`,`print", localDirSet, "ncbi_html", continueSaoWeiMap, nowYear, doiPmidSet, utMappingPmidMap, utOrPmidAndYearMap, false);
////        System.out.println("\033[31;1m" + format.format(new Date()) + " ③_1 ncbiHtmlTable->continueSaoWeiMap.size(): " + continueSaoWeiMap.size() + " " + printMemoryStr() + "\033[0m");
//
//        String ncbiArticleTable = "scholar_25_01.spider_pubmed_vip_extend_0114"; // 38270170 2025.01.16  spider_pubmed_vip_extend_38047900_1124  38270170
//        readDataTable(ncbiArticleTable, onePageNum, limit, "id", "pmid`,`doi`,`article_title`,`pub_year`,`art_type", localDirSet, "ncbi", continueSaoWeiMap, nowYear, doiPmidSet, utMappingPmidMap, utOrPmidAndYearMap, false);
//        System.out.println("\033[31;1m" + format.format(new Date()) + " ③_2 ncbiArticleTable->continueSaoWeiMap.size(): " + continueSaoWeiMap.size() + " " + printMemoryStr() + "\033[0m");
////
//        String wosArticleTable = "scholar_24_09.spider_tb_true_92007022_1125"; // spider_tb_true_csv_2024_07_12_90414577
////        readDataTable(wosArticleTable, onePageNum, limit, "pid", "UT`,`PM`,`TI`,`PY`,`DI", localDirSet, "wos", continueSaoWeiMap, nowYear, doiPmidSet, utMappingPmidMap, utOrPmidAndYearMap, false);
//        System.out.println("\033[31;1m" + format.format(new Date()) + " ③_3 wosArticleTable->continueSaoWeiMap.size(): " + continueSaoWeiMap.size() + " " + printMemoryStr() + "\033[0m");
////
//        String houTaiTable = "dir.cases_only_2024_2024_12_13_pmid"; // 14426567
////        readDataTable(houTaiTable, onePageNum, limit, "pid", "pmid", localDirSet, "houTai", continueSaoWeiMap, nowYear, doiPmidSet, utMappingPmidMap, utOrPmidAndYearMap, false);
//        System.out.println("\033[31;1m" + format.format(new Date()) + " ③_4 houTaiTable->continueSaoWeiMap.size(): " + continueSaoWeiMap.size() + " " + printMemoryStr() + "\033[0m");
//
//        // 服务器上的下载日志，文本内一行一个文件名，比如：D:\dir\2021.08.30_log_cw_525298_05.txt
//        String logFilePath = "G:\\web_104_log\\dir_web_104_log_0929.txt";
////        readLogFileBuff(logFilePath, localDirSet, continueSaoWeiMap, logSet, dirLogSaoWeiTable, isInsertLog);
//        System.out.println("\033[31;1m" + format.format(new Date()) + " ③_5 logFilePath->continueSaoWeiMap.size(): " + continueSaoWeiMap.size() + " " + printMemoryStr() + "\033[0m");
//
//        // 上次留下的需要扫尾的文件，文本内一行一个文件名，比如：D:\dir\2021.08.30_log_cw_525298_05.txt
////        String saoWeiFilePath = "F:\\SCI_HUB_60P\\淘宝文献\\WEB1113\\task\\dir_task.txt";
////        readSaoWeiFile(saoWeiFilePath, localDirSet, continueSaoWeiMap, saoWeiSet, dirLogSaoWeiTable, isInsertLog);
////        System.out.println("\033[31;1m" + format.format(new Date()) + " ③_6 saoWeiFilePath->continueSaoWeiMap.size(): " + continueSaoWeiMap.size() + " " + printMemoryStr() + "\033[0m");
//
//        // 本次需要扫尾的单纯的pmId号列表，文件内一行一个pmId号。
//        String fileName = "C:\\扫尾文件\\74629.txt";
////        readSaoWeiPmId(fileName, localDirSet, continueSaoWeiMap);
//        System.out.println("\033[31;1m" + format.format(new Date()) + " ③_7 saoWeiFilePath->continueSaoWeiMap.size(): " + continueSaoWeiMap.size() + " " + printMemoryStr() + "\033[0m");
//
//        /**
//         * 对仍然需要扫尾的，进行插表。
//         */
//        insertSaoWeiTable(saoWeiTable, continueSaoWeiMap, localDirSet, localDirSetTable, utOrPmidAndYearMap);
//        System.out.println("\033[31;1m" + format.format(new Date()) + " ④_1 saoWeiTable->utMappingPmidMap.size(): " + utMappingPmidMap.size() + " " + printMemoryStr() + "\033[0m");
//
//        // 插入映射表，要求，一个ut号只能对应一个pmid号，若有多个，给予忽略，并将结果存入pmidAndUt，再要求，一个pmid只有对应一个ut，若有多个，给予忽略，即不插入存在任何有一女多嫁的id号关系。
//        Set<String> utPmidSet = new ConcurrentHashSet<>();
//        utMappingPmidMap.keySet().parallelStream().forEach(ut -> {
//            Set<Integer> set = utMappingPmidMap.get(ut);
//            for (Integer pmid : set) {
//                String utPmid = ut + pmid;
//                if (!utPmidSet.contains(utPmid) && pmid > 0 && pmid < 50000000 && ut.length() == 15) {
//                    try {
//                        Db.use().insert(Entity.create(utMappingPmidTable).set("ut", ut.toUpperCase()).set("pmid", pmid));
//                    } catch (SQLException e) {
//                        e.printStackTrace();
//                    }
//                    utPmidSet.add(utPmid);
//                }
//            }
//        });
//        System.out.println("\033[31;1m" + format.format(new Date()) + " ④_2 utMappingPmidTable->utPmidSet.size(): " + utPmidSet.size() + " " + printMemoryStr() + "\033[0m");
//
//        long t1 = System.currentTimeMillis();
//        System.out.println(format.format(new Date()) + " 程序全部结束，总用时：" + (t1 - t0) / 1000 / 60 + " 分钟。");
//
////main
//    }
//
//    // 本地有，而服务器上无的，添加到待上传的表中。
//    public static void uploadDirFile(String dirFilePath, Set<String> localDirSet, String uploadTable) throws IOException {
//        List<String> list = FileUtil.readLines(dirFilePath, Utils.codeString(dirFilePath));
//        list.parallelStream().forEach(str -> {
//            if (!str.toUpperCase().contains(":\\$RECYCLE.BIN\\")) {
//                String fileId = Utils.getFileId(str);
//                if (fileId.length() > 1 && !localDirSet.contains(fileId) && !fileId.equals("PM0")) {
//                    try {
//                        Db.use().insert(Entity.create(uploadTable).set("file_id", fileId).set("fullpath", str).set("date", LocalDateTime.now()));
//                    } catch (SQLException e) {
//                        e.printStackTrace();
//                    }
//                }
//            }
//        });
//    }
//
//    // 服务器上的下载日志，文本内一行一个文件名
//    public static void readLogFileBuff(String logFilePath, Set<String> localDirSet, Map<String, Set<String>> continueSaoWeiMap, Set<String> logSet, String dirLogSaoWeiTable, boolean isInsertLog) throws IOException {
//        List<String> dirList = FileUtil.readLines(logFilePath, Utils.codeString(logFilePath));
//        dirList.parallelStream().forEach(fileName -> {
//            if (fileName.toLowerCase().endsWith(".txt")) {
//                try {
//                    BufferedInputStream in = FileUtil.getInputStream(fileName);
//                    BufferedReader reader = IoUtil.getReader(in, Utils.codeString(fileName));
//                    String str = null;
//                    while ((str = reader.readLine()) != null) {
//                        if (str.contains("预获取的跳转后的URL") || str.contains("棰勮幏鍙栫殑璺宠浆鍚庣殑URL")) {
//                            if (str.split("\\|").length >= 4 && str.split("\\|")[1].endsWith("URL")) {
//                                while (str.endsWith("|")) {
//                                    str = str.substring(0, str.length() - "|".length()).trim();
//                                }
//                                String[] strList = str.split("\\|");
//                                String url = "";
//                                int len = strList.length;
//                                for (int i = 3; i < len; i++) {
//                                    url += strList[i] + "|";
//                                }
//                                if (strList[2].toUpperCase().endsWith("].PDF")) {
//                                    str = url + strList[2];
//                                }
//                                if (NumberUtil.isInteger(strList[2])) {
//                                    str = url + "A[PMIDT" + strList[2] + "].PDF";
//                                }
//                            }
//                            String fileId = Utils.getFileId(str);
//                            String downUrl = reDownUrl(str);
//                            if (fileId.length() > 1 && !localDirSet.contains(fileId) && downUrl.length() > 6) {
//                                Utils.putStrSetStr(fileId, downUrl, continueSaoWeiMap);
//                            }
//                            // 对从log日志中读取出来的file_id进行插表。
//                            if (isInsertLog && fileId.length() > 1 && !logSet.contains(fileId)) {
//                                logSet.add(fileId);
//                                insertDirLogSaoWeiTable(dirLogSaoWeiTable, fileId, str, fileName, "log");
//                            }
//                        }
//                    }
//                    IoUtil.close(reader);
//                    IoUtil.close(in);
//                } catch (Exception ex) {
//                    ex.printStackTrace();
//                }
//            }
//        });
//    }
//
//    // 插入日志等中间结果信息。
//    public static void insertDirLogSaoWeiTable(String dirLogSaoWeiTable, String fileId, String url, String fileName, String type) {
//        try {
//            Db.use().insert(Entity.create(dirLogSaoWeiTable).set("file_id", fileId).set("url", url).set("file_name", fileName).set("type", type));
//        } catch (SQLException e) {
//            e.printStackTrace();
//        }
//    }
//
//    // 对仍然需要扫尾的，进行插表。
//    public static void insertSaoWeiTable(String saoWeiTable, Map<String, Set<String>> continueSaoWeiMap, Set<String> localDirSet, String localDirSetTable, Map<String, Integer> utOrPmidAndYearMap) {
//        continueSaoWeiMap.keySet().forEach(fileId -> {
//            if (!localDirSet.contains(fileId) && !fileId.startsWith("PM0")) {
//                Set<String> set = continueSaoWeiMap.get(fileId);
//                Set<String> doiNumSet = new HashSet<>();
//                StringBuilder url = new StringBuilder();
//                for (String s : set) {
//                    s = s.replace("https://doi.123456789", "");
//                    if (s.length() > 6 && !s.contains("yuntsg.com")) {
//                        url.append(s.trim()).append("||");
//                        doiNumSet.add(s);
//                    }
//                }
//                if (url.toString().endsWith("||")) {
//                    url = new StringBuilder(url.substring(0, url.length() - "||".length()));
//                }
//                // 如果含有url才保存到继续扫尾表中，如果注掉则不要求这一点。
////                if (url.length() > 6) {
//                Integer year = 2100;
//                if (utOrPmidAndYearMap.containsKey(fileId)) {
//                    year = utOrPmidAndYearMap.get(fileId);
//                }
//                try {
//                    Db.use().insert(Entity.create(saoWeiTable).set("file_id", fileId).set("doi_num", doiNumSet.size()).set("year", year).set("url", url.toString()));
//                } catch (SQLException e) {
//                    e.printStackTrace();
//                }
////                }
//            }
//        });
//        // 这个一般是不需要的2023_02.14，仅是为了核对程序时使用
////        localDirSet.parallelStream().forEach(fileId -> {
////            try {
////                Db.use().insert(Entity.create(localDirSetTable).set("file_id", fileId));
////            } catch (SQLException e) {
////                e.printStackTrace();
////            }
////        });
//    }
//
//    // 对下载的url进行规范
//    public static String reDownUrl(String downUrl) {
//        downUrl = downUrl.replace(" ", "").trim();
//        if (downUrl.indexOf("|") > 6 && downUrl.split("\\|").length == 2) {
//            downUrl = downUrl.substring(0, downUrl.indexOf("|")).trim();
//        }
//        if (downUrl.startsWith("10.")) {
//            downUrl = "https://doi.org/" + downUrl.trim();
//        }
//        if (downUrl.toLowerCase().startsWith("ftp") || downUrl.startsWith("/") || !downUrl.startsWith("http")) {
//            return "";
//        }
//        return downUrl;
//    }
//
//    // 本次需要扫尾的单纯的pmId号列表，文件内一行一个pmId号。
//    public static void readSaoWeiPmId(String fileName, Set<String> localDirSet, Map<String, Set<String>> continueSaoWeiMap) {
//        List<String> fileList = FileUtil.readLines(fileName, Utils.codeString(fileName));
//        for (String pmIdStr : fileList) {
//            if (NumberUtil.isInteger(pmIdStr)) {
//                pmIdStr = "PM" + pmIdStr;
//                String downUrl = "https://doi.123456789";
//                if (!localDirSet.contains(pmIdStr) && !pmIdStr.equals("PM0")) {
//                    Utils.putStrSetStr(pmIdStr, downUrl, continueSaoWeiMap);
//                }
//            }
//        }
//    }
//
//    // 上次留下的需要扫尾的文件，文本内一行一个文件名，比如：D:\dir\2021.08.30_log_cw_525298_05.txt
//    public static void readSaoWeiFile(String saoWeiFilePath, Set<String> localDirSet, Map<String, Set<String>> continueSaoWeiMap, Set<String> saoWeiSet, String dirLogSaoWeiTable, boolean isInsertLog) throws IOException {
//        List<String> dirList = FileUtil.readLines(saoWeiFilePath, Utils.codeString(saoWeiFilePath));
//        dirList.parallelStream().forEach(fileName -> {
//            if (fileName.toLowerCase().endsWith(".txt")) {
//                List<String> file = FileUtil.readLines(fileName, Utils.codeString(fileName));
//                for (String str : file) {
//                    String fileId = Utils.getFileId(str.replace("\"", ""));
//                    String downUrl = reDownUrl(str) + "https://doi.123456789";
//                    if (fileId.length() > 1 && !localDirSet.contains(fileId) && downUrl.length() > 6 && !fileId.equals("PM0")) {
//                        Utils.putStrSetStr(fileId, downUrl, continueSaoWeiMap);
//                    }
//                    // 对从SaoWei日志中读取出来的file_id进行插表。
//                    if (isInsertLog && fileId.length() > 1 && !saoWeiSet.contains(fileId)) {
//                        saoWeiSet.add(fileId);
//                        insertDirLogSaoWeiTable(dirLogSaoWeiTable, fileId, str, fileName, "SaoWei");
//                    }
//                }
//            }
//        });
//    }
//
//    // 本地的dir文件，文本内一行一个dir文件，比如：E:\E\SCI_HUB_44P\web0923\5\A[WOSN000612597000006].PDF
//    public static void readDirFile(String dirFilePath, Set<String> localDirSet, Set<String> dirSet, String dirLogSaoWeiTable, boolean isInsertLog) throws IOException {
//        List<String> list = FileUtil.readLines(dirFilePath, Utils.codeString(dirFilePath));
//        for (String str : list) {
//            if (!str.toUpperCase().contains(":\\$RECYCLE.BIN\\")) {
//                String fileId = Utils.getFileId(str);
//                if (fileId.length() > 1) {
//                    localDirSet.add(fileId);
//                }
//                // 对从dir日志中读取出来的file_id进行插表。
//                if (isInsertLog && fileId.length() > 1 && !dirSet.contains(fileId)) {
//                    dirSet.add(fileId);
//                    insertDirLogSaoWeiTable(dirLogSaoWeiTable, fileId, str, dirFilePath, "dir");
//                }
//            }
//        }
//    }
//
//    // 已经给淘宝的记录，文本内一行一条记录，只有PMID号，比如： 34281884
//    public static void readTaoBaoFile(String taoBaoFilePath, Set<String> localDirSet) {
//        List<String> list = FileUtil.readLines(taoBaoFilePath, Utils.codeString(taoBaoFilePath));
//        for (String str : list) {
//            if (NumberUtil.isInteger(str) && !str.startsWith("0") && str.length() < 9) {
//                localDirSet.add("PM" + str);
//            }
//        }
//    }
//
//    // 已经处理过很多遍，不打算再次处理的记录，包括UT、PM、GG三种，添加到localDirSet，相当于给予移删，不再处理了。文本内一行一条记录，比如： UT000766308400017
//    public static void readRemoveFile(String removeFilePath, Set<String> localDirSet) {
//        List<String> list = FileUtil.readLines(removeFilePath, Utils.codeString(removeFilePath));
//        for (String str : list) {
//            str = str.toUpperCase().replace("\"", "").trim();
//            if (str.startsWith("PM") || str.startsWith("UT") || str.startsWith("GG")) {
//                localDirSet.add(str);
//            } else {
//                String fileId = Utils.getFileId(str);
//                if (fileId.length() > 1) {
//                    localDirSet.add(fileId);
//                }
//            }
//        }
//    }
//
//    // 获取规范的标题
//    public static String reTitle(String title) {
//        if (null == title || title.length() < 6) {
//            return "";
//        }
//        title = title.toLowerCase().replace("-", "").replace(",", "").replace(".", "").replace(":", "").replace("?", "").replace(";", "").replace("!", "").replaceAll(" +", "").trim();
//        if (title.length() > 72) {
//            return title.substring(0, 72);
//        }
//        return title;
//    }
//
//
//    public static void readDataTable(String serverPdfTable, Integer onePageNum, String limit, String autoId, String field, Set<String> localDirSet, String type, Map<String, Set<String>> continueSaoWeiMap, String nowYear, Set<String> doiPmidSet,
//                                     Map<String, Set<Integer>> utMappingPmidMap, Map<String, Integer> utOrPmidAndYearMap, boolean print) throws SQLException {
//        SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
//        List<Entity> tableNum = Db.use().query("select count(1) as count from " + serverPdfTable);
//        if (tableNum.get(0).getInt("count") > 0) {
//            int tableMax = Db.use().queryNumber("select max(" + autoId + ") from " + serverPdfTable).intValue();
//            Collection<Integer> tableList = new ArrayList<>();
//            NumberUtil.appendRange(0, tableMax + onePageNum, onePageNum, tableList);
//            for (Integer startId : tableList) {
//                List<Entity> tableData = Db.use().query("select `" + autoId + "`,`" + field + "` from " + serverPdfTable + " where " + autoId + " between " + startId + " and " + (startId + onePageNum - 1) + limit);
//                if (print) {
//                    System.out.println("\033[31;1m" + format.format(new Date()) + " 读表现在开始：" + startId + " 表名：" + serverPdfTable + Utils.printMemoryStr() + "\033[0m");
//                }
//                for (Entity entry : tableData) {
//
//                    if ("update".equals(type)) {
//                        Integer entry_id = entry.getInt(autoId);
//                        String entry_field = entry.getStr(field);
//                        if (null != entry_id && entry_id > 0 && null != entry_field && entry_field.length() > 10) {
//                            int pid = entry_id;
//                            String fileId = Utils.getFileId(entry_field);
//                            try {
//                                Db.use().update(Entity.create().set("file_id", fileId), Entity.create(serverPdfTable).set("pid", pid));
//                            } catch (SQLException e) {
//                                e.printStackTrace();
//                            }
//                        }
//                    }
//                    if ("dir".equals(type)) {
//                        String entry_field = entry.getStr(field);
//                        if (null != entry_field && entry_field.length() > 10) {
//                            String fileId = Utils.getFileId(entry_field);
//                            if (fileId.length() > 1) {
//                                localDirSet.add(fileId);
//                            }
//                        }
//                    }
//                    if ("wos".equals(type)) {
//                        String entry_ut = entry.getStr("UT");
//                        if (null != entry_ut && entry_ut.length() > 14) {
//                            String ut = "UT" + entry_ut.toUpperCase().replace(" ", "").replace("WOS:", "").trim();
//                            Integer year = Utils.getPubYear(Utils.getStrField(entry, "PY"));
//                            if (year > 0) {
//                                utOrPmidAndYearMap.put(ut, year);
//                            }
//                            String entry_di = entry.getStr("DI");
//                            String entry_ti = entry.getStr("TI");
//                            List<String> doiList = new ArrayList<>();
//                            if (null != entry_di && entry_di.length() > 6 && entry_di.trim().startsWith("10.")) {
//                                String[] list = entry_di.trim().split("; ");
//                                for (String doi : list) {
//                                    if (doi.startsWith("10.") && doi.length() > 6) {
//                                        doiList.add("https://doi.org/" + doi.replace(" ", "").trim());
//                                    }
//                                }
//                            }
//                            String pm = "";
//                            boolean bool = false;
//                            String entry_pm = entry.getStr("PM");
//                            if (null != entry_pm && !entry_pm.isEmpty() && NumberUtil.isInteger(entry_pm.replace(" ", "").trim())) {
//                                pm = "PM" + entry_pm.replace(" ", "").trim();
//                                int pmid = Integer.parseInt(entry_pm.replace(" ", "").trim());
//                                String title = reTitle(entry_ti);
//                                if (title.length() > 5) {
//                                    if (doiPmidSet.contains(title + pm) && ut.length() == 17 && !pm.startsWith("PM0")) {
//                                        bool = true;
//                                        Utils.putStrSetInt(ut.substring("UT".length()), pmid, utMappingPmidMap);
//                                    }
//                                }
//                                for (String doi : doiList) {
//                                    String doiPmid = (doi + pm).substring("https://doi.org/".length()).toLowerCase().trim();
//                                    if (doiPmidSet.contains(doiPmid) && ut.length() == 17 && !pm.startsWith("PM0")) {
//                                        bool = true;
//                                        Utils.putStrSetInt(ut.substring("UT".length()), pmid, utMappingPmidMap);
//                                    }
//                                }
//                                // 如果localDirSet包含了pm，则将与之相对应的ut加到localDirSet里面。但如果localDirSet包含了ut，则不能直接加入localDirSet。
//                                if (localDirSet.contains(pm) && !pm.startsWith("PM0") && bool) {
//                                    localDirSet.add(ut);
//                                }
//                            }
//                            // 1、ut号有全文，pm没有全文，不下载pm号（其一已经建立起了映射表，不需要保存两份，其二，两个NC表中均无，很有可能是电子优先或此PMID已删除）；2、pm号有全文，ut号没有全文，不下载ut号；3、ut号和pm号均没有全文，则下载pm号。
//                            if (localDirSet.contains(ut) && !pm.startsWith("PM0") && bool) {
//                                localDirSet.add(pm);
//                            }
//                            if (!localDirSet.contains(ut)) {
//                                if (pm.isEmpty()) {
//                                    for (String doi : doiList) {
//                                        Utils.putStrSetStr(ut, doi, continueSaoWeiMap);
//                                    }
//                                } else {
//                                    if (pm.startsWith("PM") && !pm.startsWith("PM0")) {
//                                        // 如果没有ut也没有pm，则优先下载pm，但必须pm+title或者pm+doi号与nc中的相同。
//                                        if (!localDirSet.contains(pm) && bool) {
//                                            for (String doi : doiList) {
//                                                Utils.putStrSetStr(pm, doi, continueSaoWeiMap);
//                                            }
//                                        }
//                                        // 如果在nc中的pm和doi与wos中的pm和doi相同，则认为此ut和pm是相同的，会插入映射表中，若插入映射表则不再扫尾此ut号，若不相同，则将此ut号放入继续扫尾中。
//                                        if (bool) {
//                                            localDirSet.add(ut);// 3、ut号和pm号均没有全文，则下载pm号。
//                                        } else {
//                                            for (String doi : doiList) {
//                                                Utils.putStrSetStr(ut, doi, continueSaoWeiMap);
//                                            }
//                                        }
//                                    }
//                                }
//                            }
//                        }
//                    }
//                    // 0-Publisher;1-In-Data-Review;2-MEDLINE;3-In-Process;4-PubMed-not-MEDLINE;5-未知。如果是当前年的，必须为非出版社上传的，如果不是当前年的，所有的都要下载。  pmid`,`doi`,`pub_year`,`art_type
//                    if ("ncbi".equals(type)) {
//                        Integer entry_pmid = entry.getInt("pmid");
//                        if (null != entry_pmid && entry_pmid > 0) {
//                            String pub_year = entry.getStr("pub_year");
//                            Integer art_type = entry.getInt("art_type");
//                            String entry_doi = entry.getStr("doi");
//                            String article_title = entry.getStr("article_title");
//                            String pm = "PM" + entry_pmid.toString();
//                            Integer year = Utils.getPubYear(pub_year);
//                            if (year > 0) {
//                                utOrPmidAndYearMap.put(pm, year);
//                            }
//                            String title = reTitle(article_title);
//                            if (title.length() > 5) {
//                                doiPmidSet.add(title + pm);
//                            }
//                            if (null != pub_year && pub_year.equals(nowYear) && null != art_type && art_type.equals(0)) {
//                                localDirSet.add(pm);
//                            }
//                            String doi = "";
//                            if (null != entry_doi && entry_doi.length() > 6 && entry_doi.startsWith("10.")) {
//                                doi = "https://doi.org/" + entry_doi.replace(" ", "").trim();
//                                doiPmidSet.add((doi + pm).substring("https://doi.org/".length()).toLowerCase().trim());
//                            }
//                            if (!localDirSet.contains(pm) && !pm.startsWith("PM0")) {
//                                Utils.putStrSetStr(pm, doi, continueSaoWeiMap);
//                            }
//                        }
//                    }
//                    if ("houTai".equals(type)) {
//                        Integer entry_pmid = entry.getInt("pmid");
//                        if (null != entry_pmid && entry_pmid > 0) {
//                            String pm = "PM" + entry_pmid.toString();
//                            if (!localDirSet.contains(pm) && !pm.startsWith("PM0")) {
//                                Utils.putStrSetStr(pm, "https://doi.org/10.254578.23145.21557.yuntsg.com", continueSaoWeiMap);
//                            }
//                        }
//                    }
//                    // 如果出版时间是当前年，那么必须不能是电子优先，如果不是当前年，则一切都可以下载。  "pmid`,`citationDoi`,`text`,`redirection_notice`,`print"  如果重定向（即redirection_notice有值），则不下载此条。
//                    if ("ncbi_html".equals(type)) {
//                        Integer entry_pmid = entry.getInt("pmid");
//                        if (null != entry_pmid && entry_pmid > 0) {
//                            String pm = "PM" + entry_pmid.toString();
//                            String entry_text = entry.getStr("text");
//                            Integer year = Utils.getPubYear(entry_text);
//                            if (year > 0) {
//                                utOrPmidAndYearMap.put(pm, year);
//                            }
//                            String entry_print = entry.getStr("print");
//                            Integer redirection_notice = entry.getInt("redirection_notice");
//                            String entry_citationDoi = entry.getStr("citationDoi");
//                            String entry_citationTitle = entry.getStr("citationTitle");
//                            String title = reTitle(entry_citationTitle);
//                            if (title.length() > 5) {
//                                doiPmidSet.add(title + pm);
//                            }
//                            if ((null != entry_text && entry_text.contains(nowYear) && null != entry_print && entry_print.contains("Online ahead of print."))
//                                    || (null != redirection_notice && redirection_notice > 0)) {
//                                localDirSet.add(pm);
//                            }
//                            String doi = "";
//                            if (null != entry_citationDoi && entry_citationDoi.length() > 6 && entry_citationDoi.trim().startsWith("10.")) {
//                                doi = "https://doi.org/" + entry_citationDoi.replace(" ", "").trim();
//                                doiPmidSet.add((doi + pm).substring("https://doi.org/".length()).toLowerCase().trim());
//                            }
//                            if (!localDirSet.contains(pm) && !pm.startsWith("PM0")) {
//                                Utils.putStrSetStr(pm, doi, continueSaoWeiMap);
//                            }
//                        }
//                    }
//                }
//            }
//        }
//    }
//
//    // 服务器上的全文表，仅一个fullpath字段，比如：2018/20180617/Serum-gastrin in vitiligo [PMIDS4132789].pdf
////    public static void readDataTable(String serverPdfTable, Integer onePageNum, String limit, String autoId, String field, Set<String> localDirSet, String type, Map<String, Set<String>> continueSaoWeiMap, String nowYear, Set<String> doiPmidSet,
////                                     Map<String, Set<Integer>> utMappingPmidMap, Map<String, Integer> utOrPmidAndYearMap, boolean print) throws SQLException {
////        SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
////        List<Integer> tempNum = Collections.synchronizedList(new ArrayList<>());
////        int from = 1;
////        int max = 0;
////        List<Entity> tableNum = Db.use().query("select count(1) as count from " + serverPdfTable);
////        int count = tableNum.get(0).getInt("count");
////        if (count > 0) {
////            max = Db.use().queryNumber("select max(" + autoId + ") from " + serverPdfTable).intValue();
////        }
////        int page = max / onePageNum;
////        if (max % onePageNum != 0) {
////            page++;
////        }
////        List<OftenUtils.PageInfo> pageInfos = new ArrayList<>();
////        for (int i = 1; i <= page; i++) {
////            int start = (i - 1) * onePageNum + from;
////            int stop = i * onePageNum + from - 1;
////            if (stop > max) {
////                stop = max + onePageNum;
////            }
////            pageInfos.add(new OftenUtils.PageInfo(start, stop));
////        }
////        int numAll = pageInfos.size();
////        pageInfos.forEach(pg -> {
////            try {
////                List<Entity> tableData = Db.use().query("select `" + autoId + "`,`" + field + "` from " + serverPdfTable + " where " + autoId + " between " + pg.getFrom() + " and " + pg.getTo() + limit);
////                tempNum.add(pg.getFrom());
////                if (print && tempNum.size() % 10000 == 0) {
////                    System.out.println(format.format(new Date()) + " 现在开始： " + pg.getFrom() + " -- " + pg.getTo() + " 总条数： " + numAll + " 目前已处理： " + tempNum.size() + " 表名： " + serverPdfTable);
////                }
////                for (Entity entry : tableData) {
////                    if (null != entry) {
////                    }
////                }
////            } catch (SQLException e) {
////                e.printStackTrace();
////            }
////        });
////    }
//
//    public static String printMemoryStr() {
//        String freeMemory = null;
//        String totalMemory = null;
//        String maxMemory = null;
//        try {
//            freeMemory = Runtime.getRuntime().freeMemory() / 1024 / 1024 / 1024 + " Gb";
//            totalMemory = Runtime.getRuntime().totalMemory() / 1024 / 1024 / 1024 + " Gb";
//            maxMemory = Runtime.getRuntime().maxMemory() / 1024 / 1024 / 1024 + " Gb";
//            return " 内存申请：" + maxMemory + " 空余：" + freeMemory + " 获取：" + totalMemory;
//        } catch (Exception e) {
//            e.printStackTrace();
//        }
//        return "";
//    }
//
//
////end
//}
